package com.cj.springmvc.test.web;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.cj.springmvc.test.bo.PersonsBo;
import com.cj.springmvc.test.bo.SendAlertBo;
import com.cj.springmvc.test.dto.PersonsDto;

/**
 * 测试：登陆注册入口Controller
 * @author cj
 *
 */
@Controller
@Scope("prototype")
public class EntryController {
	private Logger log = Logger.getLogger(EntryController.class);
	
	@Resource(name = "personsBo")
	private PersonsBo personsBo;
	@Resource(name = "sendAlertBo")
	private SendAlertBo sendAlertBo;
	
	@RequestMapping("helloSpringmvc")
	public String helloSpringmvc(){
		return "hello";
	}
	/**
	 * 前往登陆页面
	 * 
	 * */
	@RequestMapping("gotoLogin")
	public String gotoLogin(){
		return "login";
	}
	
	/**
	 * 登陆操作,疑问之一：是否使用了Spring Security 之后，此方法是否即被取代。
	 * @param RedirectAttributes 重定向参数,用于redirect跳转时可传递参数，仅适用于Spring3.1以上版本
	 * */
	@RequestMapping("login")
	public String login(Model model, RedirectAttributes redirect,
			@ModelAttribute()PersonsDto dto){
		/*PersonsDto dto = new PersonsDto();
		dto.setUsername(username);
		dto.setPassword(password);*/
		log.info("登陆用户名为:=================>"+dto.getUsername());
		log.info("登陆密码名为:=================>"+dto.getPassword());
		if(!this.personsBo.doCheckLoginIsValid(dto)){
			redirect.addFlashAttribute("msg", "错误的账号或者密码！");
			return "redirect:gotoLogin";
		}
		model.addAttribute("username", dto.getUsername());
		return "index";
	}
	
	/**
	 * 退出，如同login方法一样，此方法的作用由Spring Security 完成
	 * */
//	@RequestMapping("logout")
//	public String logout(){
//		return "";
//	}
	
	/**
	 * 前往注册页面
	 * */
	@RequestMapping("gotoRegister")
	public String gotoRegister(Model model){
		model.addAttribute("dto", new PersonsDto());
		return "register";
	}
	
	/**注册验证<br>
	 *  @Valid @ModelAttribute 必须出现在BindingResult 之前，否则报错。
	 * 另外，需要在configuration file中标注需要使用到支持JSR-303 的mvc namespace
	 * @param dto
	 * @param result BindingResult 用于验证注册用户信息是否合法,与spring tag errors 结合使用，auto-render
	 * @param redirect <br>
	 * */
	@RequestMapping(value="register" ,method = RequestMethod.POST)
	public String register(@Valid @ModelAttribute("dto") PersonsDto dto ,
			BindingResult result,Model model,
			HttpServletResponse response,RedirectAttributes redirect) /*throws BindException*/{
		if(result.hasErrors()){
//			throw new BindException(result);
			// 遍历注册非法用户信息
			List<ObjectError> errors = result.getAllErrors();
			for (ObjectError error : errors) {
				log.info("注册失败信息："+ error.getObjectName());
				log.info("注册失败信息："+ error.getDefaultMessage());
			}
			model.addAttribute("dto", dto);
			return "register";
		}
		this.personsBo.doSaveNewmember(dto);
		// if the jms server can't be connected ,we will get a exception 
		this.sendAlertBo.sendAlert(dto);
		redirect.addFlashAttribute("msg", "注册成功！！");
		return "redirect:gotoLogin";
	}
	/**
	 * 检测用户名是否已占用
	 * */
	@RequestMapping("checkUsername")
	public void checkUsername(@RequestParam(defaultValue="")String username,
			HttpServletResponse response) throws IOException{
		if(this.personsBo.doCheckIsUsernameAvailable(username)){
			response.setHeader("Cache-Control", "no-cache");
			response.setContentType("text/html;charset=utf-8");
			response.getWriter().write("available");
			response.getWriter().flush();
		}
	}
	
	/*@ExceptionHandler(BindException.class)
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public void handleBindException() {}*/
}
